#include <QDir>
#include <QtSql/QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>

#include "dbmysql.h"
#include "hbot.h"
#include "sdefs.h"

CDBMySQL::CDBMySQL(const QString &server, const QString &database, const QString &user, const QString &password, quint16 port)
{
	m_Database = QSqlDatabase::addDatabase("QMYSQL");
	m_Database.setHostName(server);
	m_Database.setDatabaseName("mysql");
	m_Database.setUserName(user);
	m_Database.setPassword(password);
	m_Database.setPort(port);

	m_DatabaseName = database;
	m_ThreadGoal = 0;

	connect(this, SIGNAL(PrintConsoleThread(const QString &, const QString &, const QString &, bool)), g_HBotPtr, SLOT(PrintConsole(const QString &, const QString &, const QString &, bool)));
	connect(this, SIGNAL(SetDatabase(bool)), g_HBotPtr, SLOT(SetOpenDatabase(bool)));
}

CDBMySQL::~CDBMySQL()
{
	
}

void CDBMySQL::run()
{
	if (m_ThreadGoal == 0)
	{
		if (!m_Database.open())
		{
			m_Error = "Error: Unable to establish a database connection to server [" + m_Database.hostName() + "], database [" + m_Database.databaseName() + "], user [" + m_Database.userName() + "], port [" + QString::number(m_Database.port()) + "], using password: [" + (m_Database.password().isEmpty() ? "No" : "Yes") + "]";
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, m_Error, "MySQL", true);
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, m_Database.lastError().text(), "MySQL", true);
			emit SetDatabase(false);
			return;
		}

		QSqlQuery query;
		
		if (!query.exec("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '" + m_DatabaseName + "'"))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Error: Unable to check if database [" + m_DatabaseName + "] exists on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
			emit SetDatabase(false);
			return;
		}
		else
		{
			query.next();

			if (query.record().count() == 1)
			{
				if (query.value(0).toString().isEmpty())
				{
					emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "The MySQL database you have selected to connect to does not exist. Creating database [" + m_DatabaseName + "] immediately and populating it with necessary tables.", "MySQL");
					
					if (!query.exec("CREATE DATABASE IF NOT EXISTS " + m_DatabaseName))
					{
						emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
						emit SetDatabase(false);
						return;
					}
				}
			}
		}

		if (!query.exec("USE " + m_DatabaseName))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to select database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
			emit SetDatabase(false);
			return;
		}

		if (!query.exec(MYSQL_CREATE_TABLE_BANS))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [bans] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_GAMES))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [games] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_GAMEPLAYERS))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [gameplayers] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_DOTAGAMES))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [dotagames] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_DOTAPLAYERS))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [dotaplayers] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_USERS))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [users] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_W3MMDPLAYERS))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [w3mmdplayers] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_W3MMDVARS))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [w3mmdvars] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		if (!query.exec(MYSQL_CREATE_TABLE_SCORES))
		{
			emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Warning: Unable to create table [scores] in MySQL database [" + m_DatabaseName + "] on server [" + m_Database.hostName() + "] - " + query.lastError().text() + ".", "MySQL", true);
		}

		emit PrintConsoleThread(PRINT_CONSOLE_GROUP_DATABASE, "Successfully established a connection to server [" + m_Database.hostName() + "], database [" + m_DatabaseName + "], user [" + m_Database.userName() + "], port [" + QString::number(m_Database.port()) + "], using password: [" + (m_Database.password().isEmpty() ? "No" : "Yes") + "]", "MySQL");
		emit SetDatabase(true);
	}
	else if (m_ThreadGoal == 1)
	{
		m_Database.close();
		QSqlDatabase::removeDatabase(m_Database.database().connectionName());
	}
}
